package studio.xiaoyun.core.parameter.criterion;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

import studio.xiaoyun.core.exception.CoreException;
import studio.xiaoyun.core.parameter.Parameter;

public abstract class Criterion implements Serializable {
	private static final long serialVersionUID = 8024525790991318591L;

	public abstract List<String> getPropertyName();

	public abstract String getQuery(Parameter parameter);

	/**
	 * 获得参数类中某个属性的数据类型
	 * @param parameter 参数类的实例
	 * @param fieldName 属性名称
	 * @return 数据类型
	 */
	protected DataType getDataType(Parameter parameter, String fieldName) {
		DataType result = DataType.UNKNOWN;
		Class<?> type = this.getFieldByName(parameter, fieldName).getType();
		if (type == Integer.class || type == Integer.TYPE || type == Double.class || type == Double.TYPE
				|| type == Short.class || type == Short.TYPE || type == BigDecimal.class || type==Long.class
				|| type == Long.TYPE) {
			result = DataType.NUMBER;
		} else if (type == String.class) {
			result = DataType.STRING;
		} else if (type.isEnum()) {
			result = DataType.ENUM;
		} else if (type == Date.class || type == java.sql.Date.class || type == Timestamp.class) {
			result = DataType.DATE;
		} else {
			result = DataType.UNKNOWN;
		}
		return result;
	}
	
	/**
	 * 根据名称查找属性
	 * @param parameter Parameter类的实例
	 * @param fieldName 名称
	 * @return 属性
	 * @throws CoreException 如果没有找到，则抛出异常
	 */
	protected Field getFieldByName(Parameter parameter,String fieldName)throws CoreException{
		Field result = null;
		List<Field> fieldList = new LinkedList<Field>();
		Field[] fields = parameter.getClass().getDeclaredFields();
		fieldList.addAll(Arrays.asList(fields));
		Class<?> superClass = parameter.getClass().getSuperclass();
		while (superClass != Object.class && superClass != Parameter.class) {
			fields = superClass.getDeclaredFields();
			fieldList.addAll(Arrays.asList(fields));
			superClass = superClass.getSuperclass();
		}
		for (Field field : fieldList) {
			if (field.getName().equals(fieldName)) {
				result = field;
				break;
			}
		}
		if(result==null){
			throw new CoreException(parameter.getClass().getName()+"中不存在属性"+fieldName);
		}
		return result;
	}

	/**
	 * 以"yyyy-MM-dd HH:mm:ss"格式将日期转换为字符串
	 * @param date 日期
	 * @return 字符串格式的日期
	 */
	protected String formatDate(Date date){
		SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		return format.format(date);
	}
}
